//
//  ProtocolStream.m
//  Protocol
//
//  Created by  user on 11-1-8.
//  Copyright 2011 GuangZhouXuanWu. All rights reserved.
//

#import "BitConvert.h"


@implementation CBitConvert

+(void)toIntBuffer:(int)nDigit inoutput:(char*)buffer
{
    int n = ToInt nDigit;
	memcpy(buffer,&n,sizeof(int));
}

+(int)fromIntBuffer:(char*)buffer
{
	return *(int*)buffer;
}

+(void)toIntArray:(int)nDigit inoutput:(CMemoryStream*)buffer output:(NSUInteger*)nOffset
{
    int n = ToInt nDigit;
	[buffer appendBytes:&n length:sizeof(int)];
	*nOffset+=sizeof(int);
}

+(int)fromIntArray:(CMemoryStream*)buffer output:(NSUInteger*)nOffset
{
	char buf[sizeof(int)];
	[buffer getBytes:buf range:NSMakeRange([buffer position],sizeof(int))];
	*nOffset+=sizeof(int);
	return *(int*)buf;
}

+(void)toShortArray:(short)nDigit inoutput:(CMemoryStream*)buffer output:(NSUInteger*)nOffset
{
	[buffer appendBytes:&nDigit length:sizeof(short)];
	*nOffset+=sizeof(short);
}

+(short)fromShortArray:(CMemoryStream*)buffer output:(NSUInteger*)nOffset
{
	char buf[sizeof(short)];
	[buffer getBytes:buf range:NSMakeRange([buffer position],sizeof(short))];
	*nOffset+=sizeof(short);
	return *(short*)buf;
}

+(void)toLongLongArray:(long long)nDigit inoutput:(CMemoryStream*)buffer output:(NSUInteger*)nOffset
{
	[buffer appendBytes:&nDigit length:sizeof(long long)];
	*nOffset+=sizeof(long long);
}

+(long long)fromLongLongArray:(CMemoryStream*)buffer output:(NSUInteger*)nOffset
{
	char buf[sizeof(long long)];
	[buffer getBytes:buf range:NSMakeRange([buffer position],sizeof(long long))];
	*nOffset+=sizeof(long long);
	return *(long long*)buf;
}

+(void)toCharArray:(char)ch inoutput:(CMemoryStream*)buffer output:(NSUInteger*)nOffset
{
	[buffer appendBytes:&ch length:sizeof(char)];
	*nOffset+=sizeof(char);
}

+(char)fromCharArray:(CMemoryStream*)buffer output:(NSUInteger*)nOffset
{
	char buf[sizeof(char)];
	[buffer getBytes:buf range:NSMakeRange([buffer position],sizeof(char))];
	*nOffset+=sizeof(char);
	return buf[0];
}

+(void)toStringArray:(NSString*)str inoutput:(CMemoryStream*)buffer output:(NSUInteger*)nOffset
{
	if([str length]>0)
	{
		const char* ch=[str UTF8String];	
		NSUInteger nLen = strlen(ch);
		[CBitConvert toIntArray:ToInt nLen inoutput:buffer output:nOffset];
		[buffer appendBytes:ch length:nLen];
		*nOffset+=nLen;
	}else 
	{
		Byte ch=1;	
		int nLen=0;
		[CBitConvert toIntArray:nLen inoutput:buffer output:nOffset];
		[buffer appendBytes:&ch length:1];
		*nOffset+=1;
	}
}

+(NSString*)fromStringArray:(int)strencoding buffer:(CMemoryStream*)buffer output:(NSUInteger*)nOffset
{
	NSUInteger nPos=0;
	NSString* str=nil;
	int nLen=[CBitConvert fromIntArray:buffer output:nOffset];
	nPos = *nOffset;
	if(nLen>0)
	{
		switch(strencoding)
		{
			case 2:
			{
				char* ch=malloc(sizeof(char)*(nLen+1));
				[buffer getBytes:ch range:NSMakeRange(nPos,nLen)];
				ch[nLen]='\0';
				str=[NSString stringWithUTF8String:ch];
				free(ch);
				break;
			}
			case 1:
			{
				NSData* data=[buffer subdataWithRange:NSMakeRange(nPos,nLen)];
				NSStringEncoding enc=CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
				str=[[[NSString alloc]initWithData:data encoding:enc]autorelease];
			}
		}
	}
	else
	{
		nLen=1;
		char ch[1];
		ch[0]='\0';
		str=[NSString stringWithUTF8String:ch];
	}
	*nOffset=nPos+nLen;
	return str;
}

+(void)toDateTimeArray:(NSDate*)datetime inoutput:(CMemoryStream*)buffer output:(NSUInteger*)nOffset
{
	[CBitConvert toLongLongArray:[datetime timeIntervalSince1970]*1000 inoutput:buffer output:nOffset];
}

+(NSDate*)fromDateTimeArray:(CMemoryStream *)buffer output:(NSUInteger *)nOffset
{
	return [NSDate dateWithTimeIntervalSince1970:[CBitConvert fromLongLongArray:buffer output:nOffset]/1000];
}

+(void)toGUIDArray:(GUID)guid inoutput:(CMemoryStream*)buffer output:(NSUInteger*)nOffset
{
	[buffer appendBytes:&guid length:sizeof(GUID)];
	*nOffset+=sizeof(GUID);
}

+(GUID)fromGUIDArray:(CMemoryStream *)buffer output:(NSUInteger*)nOffset
{
	char buf[sizeof(GUID)];
	[buffer getBytes:buf range:NSMakeRange([buffer position],sizeof(GUID))];
	*nOffset+=sizeof(GUID);
	return *(GUID*)buf;
}

+(NSData*)fromDataArray:(CMemoryStream*)buffer output:(NSUInteger*)nOffset
{
	NSUInteger nPos=0;
	NSData* data=nil;
	int nLen=[CBitConvert fromIntArray:buffer output:nOffset];
	nPos = *nOffset;
	if(nLen>0)
	{
		data=[buffer subdataWithRange:NSMakeRange(nPos,nLen)];
	}
	else
	{
		nLen=1;
		data=nil;
	}
	*nOffset=nPos+nLen;
	return data;
}

+(void)toDataArray:(NSData*)data inoutput:(CMemoryStream*)buffer output:(NSUInteger*)nOffset
{
	if([data length]>0)
	{
		[CBitConvert toIntArray:ToInt [data length] inoutput:buffer output:nOffset];
		[buffer appendData:data];
		*nOffset+=[data length];
	}
	else
	{
		char* ch="0";	
		int nLen=0;
		[CBitConvert toIntArray:nLen inoutput:buffer output:nOffset];
		[buffer appendBytes:ch length:1];
		*nOffset+=1;
	}
}

@end
